/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Core;



/**
 *
 * @author THINH
 */

public class Vector2 {
    public float x;
    public float y;
    public Vector2(){
        x = 0; 
        y = 0;
    }
    public Vector2(float x, float y){
        this.x = x; 
        this.y = y;
    }
    
    public float getLength(){
        return (float)Math.sqrt(x*x+y*y);
    }
    
    public static Vector2 Zero(){
        Vector2 vec = new Vector2(0,0);
        return vec;
    }
    
    public void set(Vector2 vec){
        this.x = vec.x;
        this.y = vec.y;
    }
    public void set(float x, float y){
        this.x = x;
        this.y = y;
    }
    public void add(Vector2 vec){
        x+=vec.x;
        y+=vec.y;
    }
    public void subtract(Vector2 vec){
        x-=vec.x;
        y-=vec.y;
    }
    public void multiple(float z){
        x*=z;
        y*=z;
    }
    
    public void goToZero(){
        if(x>0){
            --x;
        } else if(x<0){
            ++x;
        }
        if(y>0){
            --y;
        } else if (y<0){
            ++y;
        }
    }
    public void goToZeroX(){
        if(x>0){
            x = x-0.5f;
        } else if(x<0){
            x = x +0.5f;
        }
    }
    public float dot(Vector2 vec){
        float ret = 0;
        ret = this.getLength() * vec.getLength() * (float)Math.cos(this.getAngle(vec));
        return ret;
    }
    
    public float getAngle(Vector2 vec){
        float ret = 0;
        float thisAngle = this.getAngle();
        float vecAngle = vec.getAngle();
        if(vecAngle > thisAngle){
            ret = vecAngle - thisAngle;
        } 
        else {
            ret = thisAngle - vecAngle;
        }
        return ret;
    }
    
    public float getAngle(){
        return (float)arcSin(sin());
    }
    
   
    /*
     * Begin source code from http://www.javafr.com/
     * Author : bernardgautier
     */
    private float sin(){
        return y/getLength();
    }
    private double arcSin(double z) {
        int k,i;
        int N = 30;                   // This number determines the precision, higher it is, higher the precision is.
        double res,tmp1,tmp2,tmp3;
        
        res = 0;
        if (Math.abs(z)<=0.5) {
            // = sum(k=0 a n) de (produit de j=0 a k-1 de (0.5+j))*z exp 2k+1) div (k! * 2k+1)
            for (k=0;k<N;k++) {
                tmp1 = prod(0.5,k);
                tmp2 = 1;
                for (i=0;i<2*k+1;i++)
                    tmp2 *= z;
                tmp1 *= tmp2;
                tmp1 /= (2*k+1);
                tmp1 /= fact(k);
                
                res += tmp1;
            }
        } else if (z>0.5) {
            // = (Pi/2-Racine de 2*racine de 1-z)*Sum(k=0 a N) de (produit de j=0 a k-1 de (0.5+j))*(1-z) exp k) div (2exp k * k! * 2k+1) 
            for (k=0;k<N;k++) {
                tmp1 = prod(0.5,k);
                tmp2 = 1;
                for (i=0;i<k;i++)
                    tmp2 *= ((1-z)/2);
                tmp1 *= tmp2;
                tmp1 /= (2*k+1);
                tmp1 /= fact(k);
                
                res += tmp1;
            }
            res *= Math.sqrt(2)*Math.sqrt(1-z);
            res = Math.PI/2 - res;
        } else {
            // = (-Pi/2 + Racine de 2*racine de z+1)*Sum(k=0 a N) de (produit de j=0 a k-1 de (0.5+j))*(z+1) exp k) div (2exp k * k! * 2k+1) 
            for (k=0;k<N;k++) {
                tmp1 = prod(0.5,k);
                tmp2 = 1;
                for (i=0;i<k;i++)
                    tmp2 *= ((z+1)/2);
                tmp1 *= tmp2;
                tmp1 /= (2*k+1);
                tmp1 /= fact(k);
                
                res += tmp1;
            }
            res *= Math.sqrt(2)*Math.sqrt(z+1);
            res = res - Math.PI/2;
        }
        
        return res;
        
    }
    
    private double prod(double a,int n) {
        int k;
        double res=1;
        
        for (k=0;k<n;k++)
            res *= (a+k);
        return res;
        
    }
    /** This function calcultes the factorial
     * For n=0 return 1
     * @param n
     * @return n*(n-1)*...*2
     */
    private double fact(int n) {
        double res=1;
        for(int i=2;i<=n;i++)
            res *= i;
        return res;
    }
    /*
     * End of source code from: http://www.javafr.com/ 
     * Author : bernardgautier
     */
    
    
    
}

